package cn.push.embed.core;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

import cn.push.embed.core.socket.NioSocketConnection;
import cn.push.embed.core.socket.NioSocketConnectionHandler;
import cn.push.embed.core.utils.GetDeviceInfo;
import cn.push.embed.core.utils.Logger;
import cn.push.embed.protocol.Constant;
import cn.push.embed.protocol.JsonStruct;
import cn.push.embed.protocol.Utils;
import cn.push.embed.utils.CommonUtils;

/**
 * Created by shangdongzhou on 2017/3/29.
 */

public class ConnectServer implements Runnable {
    private static final int CONNECT=1;
    private static final int DISCONNECT=2;
    private static final int SEND_PING=3;
    private NioSocketConnection connection =new NioSocketConnection();


    private boolean mRunning;
    private  Handler mHandler;
    private ConnectServer connectServer;
    // ----- Instance-----
    private Context mContext;
    private volatile static ConnectServer sInstance;
    //初始化，获取单例
    public static void initialize(Context applicationContext) {
        if (sInstance == null) {
            synchronized (ConnectServer.class) {
                if (sInstance == null) {
                    sInstance = new ConnectServer(applicationContext);

                }
            }
        }
    }

    public static ConnectServer getInstance() {
        return sInstance;
    }

    public ConnectServer(Context mContext) {
        this.mContext = mContext;
    }

    @Override
    public void run() {
        Looper.prepare();
            mHandler = new Handler(new Handler.Callback() {
                @Override
                public boolean handleMessage(Message msg) {
                    switch (msg.what){
                        case CONNECT:
                            handleConnect();
                            break;
                        case DISCONNECT:
                            handleDisconnect();
                            break;
                        case SEND_PING:
                            handlePing();
                            break;
                    }
                    return false;
                }
            });
            mRunning = true;
        Looper.loop();
    }

    private void handlePing() {
        connection.sendPingFrame();
    }

    private void handleDisconnect() {
        connection.disConnect();
    }

    private void handleConnect() {




    }

    public void  connect(){
        this.mHandler.sendEmptyMessage(CONNECT);
    }
    public void disConnect(){
        this.mHandler.sendEmptyMessage(DISCONNECT);
    }
    public void sendPing(){
        this.mHandler.sendEmptyMessage(SEND_PING);
    }

    private void connectSocket() {
        if (CommonUtils.isEmpty(CommData.ipPort)) {
            return;
        }
        connection.connect(CommData.ipPort, new NioSocketConnectionHandler() {

            @Override
            public void onTextMessage(String payload) {

            }

            @Override
            public void onRawTextMessage(byte[] payload) {

            }

            @Override
            public void onOpen() {
                Logger.d("open");

                JsonStruct jsonStruct = new JsonStruct(GetDeviceInfo.getMetaData(mContext, "PUSH_APPKEY"),
                        "2", GetDeviceInfo.getDevices(mContext), GetDeviceInfo.getIdentity(mContext),
                        CommData.AppSecret, "PushService.this.alias");
                Logger.d(jsonStruct.toJsonString());
                byte[] data = Utils.getDataFromJson(jsonStruct.toJsonString());
                byte[] result = Utils.getSendPagectFromInt(data, Constant.DataType.LPUSH_HEADER_TYPE_HANDSHAKE);
                connection.sendBinaryMessage(result);
                Utils.printHexString(result);
            }

            @Override
            public void onClose(int code, String reason) {
                Logger.d("onClose\n" + "code:" + code + "\n reason:" + reason);
               // isConnect = false;

            }

            @Override
            public void onBinaryMessage(byte[] payload) {
                Logger.d("接收到来自服务器 的信息:"
                        + Arrays.toString(payload));
                if (payload.length > 14) {
                    byte[] header = new byte[5];
                    System.arraycopy(payload, 0, header, 0, 5);
                    if (Arrays.equals(header, Constant.FLAG)) {
                        if (payload[9] == 0x01) {
                            if (payload[14]==0x00){
                                Logger.d("handshake err");
                                return;
                            }else if (payload[14]==0x02){
                                Logger.d("screteKey err");
                            }else {
                                Logger.d("handshake success");
                                byte[] result = null;
                                try {
                                    result = Utils.getSendPagectFromInt(Utils.stringToByte("createConnection"), Constant.DataType.LPUSH_HEADER_TYPE_CREATE_CONNECTION);
                                } catch (UnsupportedEncodingException e) {
                                    e.printStackTrace();
                                }
                                connection.sendBinaryMessage(result);
                            }
                        } else if (payload[9] == Constant.DataType.LPUSH_HEADER_TYPE_CREATE_CONNECTION) {
                            //isConnect = true;
                            connection.sendPingFrame();
                        } else if (payload[9] == Constant.DataType.LPUSH_HEADER_TYPE_CLOSE) {
                           // clearAlias();
                            /*timer.cancel();
                            timer.purge();
                            timer=null;
                            System.out.println("定时器取消了");*/
                        }
                    }
                }

            }
        });
    }


}
